// CalibData.cpp : implementation file
//

#include "stdafx.h"
#include "manualCalib.h"
#include "CalibData.h"
#include "cvxSf.h"


// CCalibData

CCalibData::CCalibData()
{
	m_img = NULL;
	m_grayImg = NULL;
}

CCalibData::~CCalibData()
{
	if (m_img)
	{
		cvReleaseImage(&m_img);
	}
	if (m_grayImg)
	{
		cvReleaseImage(&m_grayImg);
	}
}

bool CCalibData::addImage(const string & fileName)
{
	m_img = cvLoadImage(fileName.c_str(), 1);
	if (m_img)
	{
		m_grayImg = cvCreateImage(cvGetSize(m_img), IPL_DEPTH_8U, 1);
		cvCvtColor(m_img, m_grayImg, CV_BGR2GRAY);		
		return true;	
	}
	return false;
}
bool CCalibData::addImage(IplImage *img, CvxBoard *board)
{
	assert(img);
	m_img = cvCloneImage(img);
	m_grayImg = cvCreateImage(cvGetSize(m_img), IPL_DEPTH_8U, 1);
	if (img->nChannels == 3)
	{
		cvCvtColor(m_img, m_grayImg, CV_BGR2GRAY);
	}
	else if (img->nChannels == 1)
	{
		cvCopy(img, m_grayImg);
	}
	m_pBoard = board;
	return true;
}
void CCalibData::addCorner(const Point2f &p)
{
	m_cornerVec.push_back(p);
	if (m_cornerVec.size() == 4)
	{
		cv::cornerSubPix(Mat(m_grayImg), m_cornerVec, cvSize(11, 11), cvSize(-1, -1), 
			TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));
	}
}

void CCalibData::Draw(CDC *pDc, float ratio)
{
	CPen aPen;
	COLORREF aColor = RGB(255, 0, 0);
	unsigned int aPenWidth = 2;

	if(!aPen.CreatePen(PS_SOLID, aPenWidth, aColor))
	{
		AfxMessageBox(_T("can not create pan for Rectangle!"), MB_OK);
		AfxAbort();
	}

	CPen *oldPen = pDc->SelectObject(&aPen);
	CBrush *oldBrush = (CBrush*)pDc->SelectStockObject(NULL_BRUSH);

	if (!m_cornerVec.empty())
	{
		pDc->MoveTo(CPoint((int)(m_cornerVec[0].x * ratio), (int)(m_cornerVec[0].y * ratio)));
		for (int i = 1; i<m_cornerVec.size(); ++i)
		{
			pDc->LineTo(CPoint((int)(m_cornerVec[i].x * ratio), (int)(m_cornerVec[i].y * ratio)));
		}
		if (m_cornerVec.size() >= 4)
		{
			pDc->LineTo((int)(m_cornerVec[0].x * ratio), (int)(m_cornerVec[0].y * ratio));
		}
		//draw rectangle around the corner point
		for (int i = 0; i<m_cornerVec.size(); ++i)
		{
			CPoint centerP((int)(m_cornerVec[i].x * ratio), (int)(m_cornerVec[i].y * ratio));
			pDc->Rectangle(CRect(centerP - CSize(10, 10),centerP + CSize(10, 10)));
		}
	}
	pDc->SelectObject(oldPen);
	pDc->SelectObject(oldBrush);
}

void CCalibData::DrawPredictedPts(CDC *pDc, float ratio, vector<Point2f> &pts)
{
	CPen aPen;
	COLORREF aColor = RGB(255, 0, 0);
	unsigned int aPenWidth = 2;

	if(!aPen.CreatePen(PS_SOLID, aPenWidth, aColor))
	{
		AfxMessageBox(_T("can not create pan for Rectangle!"), MB_OK);
		AfxAbort();
	}

	CPen *oldPen = pDc->SelectObject(&aPen);
	CBrush *oldBrush = (CBrush*)pDc->SelectStockObject(NULL_BRUSH);
	for (int i = 0; i<pts.size(); ++i)
	{
		int ul = 2;
		CvPoint p = cvPoint(cvRound(pts[i].x * ratio), cvRound(pts[i].y * ratio));

		pDc->MoveTo(CPoint(p.x-ul, p.y));
		pDc->LineTo(CPoint(p.x+ul, p.y));

		pDc->MoveTo(CPoint(p.x, p.y-ul));
		pDc->LineTo(CPoint(p.x, p.y+ul));
	}

	pDc->SelectObject(oldPen);
	pDc->SelectObject(oldBrush);

}

bool CCalibData::GetInsiderCorner(vector<Point2f> &pts, bool subPixel)
{
	if (m_pBoard)
	{
		return m_pBoard->GetInsidePoints(m_grayImg, m_cornerVec, pts);
	}
	else
	{
		return false;
	}
}

void CCalibData::deleteLastCorner()
{
	if (!m_cornerVec.empty())
	{
		m_cornerVec.resize(m_cornerVec.size()-1);
	}	
}



